import os
import sys
from random import randint
from PIL import Image as PIL_Image, ImageFont
from PIL import ImageDraw

from CommonOperations.parse_SQLite import ParseSQLite
from CommonOperations.project_root_path import project_root_path
from CommonOperations.get_all_configs import get_all_configs

def get_big_img():
    """获取大图"""
    all_configs = get_all_configs()
    project_root = project_root_path()
    search_dir = os.path.join(project_root, all_configs['big_dir'])
    big_imgs_list = os.listdir(search_dir)

    choose_imgs = []
    for f_name in big_imgs_list:
        if f_name.endswith(".jpg") or f_name.endswith(".png") or f_name.endswith(".gif"):
            choose_imgs.append(os.path.join(search_dir, f_name))
    try:
        if len(choose_imgs) < 2:
            choose_img = choose_imgs[0]
        else:
            choose_num = randint(0, len(choose_imgs))
            choose_img = choose_imgs[choose_num]

        big_img = PIL_Image.open(choose_img)
    except Exception as e:
        print("大图文件夹路径中没有合法格式图片")
        raise Exception

    return big_img

def crop_img(big_img, width, height):
    """切割对应尺寸"""
    if width < 1:
        w = big_img.size[0]
    else:
        w = width
    if height < 1:
        h = big_img.size[1]
    else:
        h = height
    small_img = big_img.crop((0, 0, w, h))
    return small_img

def add_img_border(img, border_color=None, border_width=10):
    """
    图片描边
    :param img:
    :param border_color: 描边颜色
    :param border_width: 边宽，默认10个像素
    :return:
    """
    img_w,img_h = img.size
    # 如果没有传设定的值，使用本地配置文件默认值
    all_configs = get_all_configs()
    if border_color is None:
        border_color = all_configs['border_color']
    if border_color is None:
        border_color = all_configs['border_color']

    def change_color_pixel(img, start_x, start_y, end_x, end_y,border_color):
        """
        根据给定的矩形范围修改像素颜色
        :param img:
        :param start_x:
        :param start_y:
        :param end_x:
        :param end_y:
        :param border_color:
        :return:
        """
        from PIL import ImageColor

        border_color_RGBA = ImageColor.getcolor(border_color, "RGBA")
        for w in range(start_x, end_x):
            for h in range(start_y, end_y):
                img.putpixel((w,h), border_color_RGBA)
    # 使用铺助函数，修改图片像素值
    change_color_pixel(img, 0, 0, border_width, img_h, border_color)                # 左
    change_color_pixel(img, 0, 0, img_w, border_width, border_color)                # 上
    change_color_pixel(img, img_w - border_width, 0, img_w, img_h, border_color)    # 右
    change_color_pixel(img, 0, img_h - border_width, img_w, img_h, border_color)    # 下

    return img

def save_img(img,img_name, img_type, img_dir):
    """保存图片到指定路径"""
    project_root = project_root_path()
    save_dir = os.path.join(project_root, img_dir)
    if not os.path.exists(save_dir):
        os.mkdir(save_dir)

    img_long_name = img_name + '.' +img_type.lower()
    img_path = os.path.join(save_dir, img_long_name)
    img.save(img_path)

    return img_path

def add_text_on_img(img, desc_text, font_color=None, font_size=None, border_width=20):
    """
    添加文字水印
    :param img:
    :param desc_text:
    :param font_color:
    :param font_size:
    :param border_width: 描边，默认20个像素的边距
    :return:
    """
    # 在传入的图片上添加文字水印
    draw = ImageDraw.Draw(img)

    # 注意因为要支持中文输入，需要找一个中文字体才行
    if sys.platform.startswith("darwin"):
        # mac字体
        text_font = ImageFont.truetype(font="Songti.ttc", size=font_size)
    elif sys.platform.startswith("win32"):
        # windows字体
        text_font = ImageFont.truetype(font="STXINWEI.TTF", size=font_size)

    # 文字换行
    img_width, img_height = img.size
    words_width, words_height = draw.textsize(desc_text, font=text_font)
    max_width_single_column = img_width-border_width

    import math
    text_columns = math.ceil(words_width/max_width_single_column)
    word_per_column = math.ceil(max_width_single_column/font_size)
    desc_text_list = []
    start_w = 0
    for i in range(text_columns):
        desc_text_list.append(desc_text[start_w+word_per_column*i:word_per_column*(i+1)])

    # 从(10,10)坐标开始写字，以防与图片描边冲突
    start_x, start_y = 10, 10
    for j, single_column in enumerate(desc_text_list):
        draw_y = start_y + j*words_height
        draw.text((start_x, draw_y), single_column, fill=font_color, font=text_font)

    return img

def create_img_name(img, desc_text="", whether_timestamp=False):
    """生成图片名称"""
    time_stamp = ""
    if whether_timestamp:
        import time
        time_stamp = time.strftime("%Y%m%d_%H%M%S", time.localtime())
    img_size = str(img.size[0]) + 'x' + str(img.size[1])

    # 文件名长度控制在200字内
    img_desc_origin = desc_text
    img_desc = img_desc_origin[:200].replace('\r', '').replace('\n', '').replace(' ', '_')
    img_name = '_'.join((time_stamp, img_size, img_desc))

    return img_name

def create_img(img_width=-1, img_height=-1,
               whether_add_text=False, font_color="", font_size=0, desc_text="",
               whether_add_timestamp=False, img_type="JPG", img_dir="",
               whether_add_border=False, border_color="", border_width=0):
    """
    创建单张图片
        step1 从大图切下小图:img_width, img_height
        step2 (可选)增加描边:whether_add_border, border_color, border_width
        step3 (可选)增加水印文字:whether_add_text, font_size, font_color, desc_text
        step4 保存对应格式图片:img_type, img_save_dir, img_name
        step5 将图片记录写入本地数据库

    :param img_width: 图片宽度，-1使用配置文件默认参数，0原图尺寸，大于0使用给定值
    :param img_height: 图片高度，-1使用配置文件默认参数，0原图尺寸，大于0使用给定值
    :param whether_add_text: 是否添加水印文字
    :param font_color: 水印文字颜色
    :param font_size: 水印文字大小
    :param desc_text: 文字内容
    :param whether_add_timestamp: 是否添加时间戳
    :param img_type: 图片类型，只支持"jpg/png/gif"格式
    :param img_dir: 图片保存文件夹路径
    :return: 单张图片保存的绝对路径
    """
    # 如果没有传设定的值，使用本地配置文件默认值
    all_configs = get_all_configs()
    # step1 从大图切下小图
    big_img = get_big_img()

    # img_width值=0表示原图大小/<0表示配置文件默认值/>0使用给定值
    if img_width < 0:
        crop_width = all_configs['img_w']
    elif img_width == 0:
        crop_width = big_img.size[0]
    elif img_width > 0:
        crop_width = img_width
    else:
        raise Exception("宽度数据有问题")

    # img_height值=0表示原图大小/<0表示配置文件默认值/>0使用给定值
    if img_height < 0:
        crop_height = all_configs['img_h']
    elif img_height == 0:
        crop_height = big_img.size[1]
    elif img_height > 0:
        crop_height = img_height
    else:
        raise Exception("高度数据有问题")

    step1_img = crop_img(big_img, crop_width, crop_height)

    # step2 增加描边
    if whether_add_border:
        if border_color == "":
            border_color = all_configs['border_color']
        if border_width == 0:
            border_width = all_configs['border_width']
        step2_img = add_img_border(step1_img, border_color, border_width)
    else:
        step2_img = step1_img

    # step3 增加水印文字
    if whether_add_text:
        if font_color == "":
            font_color = all_configs['font_color']
        if font_size == 0:
            font_size = all_configs['font_size']
        step3_img = add_text_on_img(step2_img, desc_text, font_color, font_size, border_width)
    else:
        step3_img = step2_img

    # step4 保存对应格式图片
    img_name = create_img_name(step3_img, desc_text, whether_add_timestamp)
    img_full_path = save_img(step3_img,img_name, img_type, img_dir)

    # step5 将图片记录写入本地数据库
    import time
    insert_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    ParseSQLite().add_img_record(crop_width, crop_height, desc_text, insert_time, img_type, img_full_path)

    return img_full_path
